package com.mugu.ipclient;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Scanner;
import java.util.Vector;

import com.mugu.Main;

public class IPClientUtils {

	/**
	 * @func changeStr
	 * @brief add delta to each byte of string
	 */
	public static String changeStr(String str, int delta) {
		byte[] tmp = str.getBytes();
		for (int i = 0; i < tmp.length; i++) {
			tmp[i] += delta;
		}
		return new String(tmp);
	}

	/**
	 * @brief return random interger [start, start + delta)
	 */
	public static int getRandomInt(int start, int delta) {
		return (int) (start + Math.random() * delta);
	}

	/**
	 * @brief generate a random string of length
	 */
	public static String getRandomString(int length) {
		byte[] choose = "0123456789abcdef".getBytes();
		byte[] tmp = new byte[length];
		for (int i = 0; i < tmp.length; i++) {
			tmp[i] = choose[(int) (Math.random() * choose.length)];
		}
		return new String(tmp);
	}

	/**
	 * @func md5String
	 * @brief do the md5 encrypt of the string(arg0), then get the hex string of
	 *        each byte of the encryption string.
	 */
	public static String md5String(String str) {
		MessageDigest digest = null;
		try {
			digest = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		byte[] aftetByet = digest.digest(str.getBytes());
		StringBuffer result = new StringBuffer();
		for (byte b : aftetByet) {
			String tmp = Integer.toHexString(b & 0xff);
			if (tmp.length() < 2) {
				tmp = "0" + tmp;
			}
			result.append(tmp);
		}
		return result.toString();
	}

	/**
	 * @func flow_encrypt
	 * @brief use the key to encrypt the password, this is a flow encryption
	 *        algorithm.
	 */
	public static String flowEncrypt(String password, int key) {
		byte[] passByte = password.getBytes();
		int vkey = key;
		for (int i = 0; i < password.length(); i++) {
			int c = passByte[i];
			int tmp = vkey;
			tmp = (tmp & 0xffff) >> 8;
		int d = tmp & 0xff;
		c = d ^ c;
		passByte[i] = (byte) c;
		int e = vkey & 0xffff;
		e = (e + c) & 0xffff;
		e = (e * 0xce6d) & 0xffff;
		e = (e + 0x58bf) & 0xffff;
		vkey = e;
		}
		return new String(passByte);
	}

	public static byte[] short2byte(short num) {
		byte[] b = new byte[2];
		int offset = 0;
		for (int i = 0; i < b.length; i++) {
			b[i] = (byte) ((num >> offset) & 0xff);
			offset += 8;
		}
		return b;
	}

	public static short byte2short(byte[] b, int start) {
		short result = 0;
		try {
			int offset = 0;
			for (int i = start; i < start + 4; i++) {
				result += (1 << offset) * (b[i] & 0xff);
				offset += 8;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static byte[] int2byte(int num) {
		byte[] b = new byte[4];
		int offset = 0;
		for (int i = 0; i < b.length; i++) {
			b[i] = (byte) ((num >> offset) & 0xff);
			offset += 8;
		}
		return b;
	}

	public static int byte2int(byte[] b, int start) {
		int result = 0;
		try {
			int offset = 0;
			for (int i = start; i < start + 4; i++) {
				result += (1 << offset) * (b[i] & 0xff);
				offset += 8;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static byte[] long2byte(long num) {
		byte[] b = new byte[8];
		int offset = 0;
		for (int i = 0; i < b.length; i++) {
			b[i] = (byte) ((num >> offset) & 0xff);
			offset += 8;
		}
		return b;
	}

	public static long byte2long(byte[] b, int start) {
		long result = 0;
		try {
			int offset = 0;
			for (int i = start; i < start + 8; i++) {
				result += (1L << offset) * (b[i] & 0xff);
				offset += 8;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static double byte2double(byte[] b, int start) {
		long n = byte2long(b, start);
		if (n == 0) {
			return 0;
		}
		double mantissa = n & 0x000fffffffffffffL;
		mantissa += (1L << (13 * 4));
		mantissa /= (1L << (13 * 4));
		int exponent = (int) ((n & 0x7ff0000000000000L) >> 13 * 4);
		mantissa *= Math.pow(2, exponent - 1023);
		if (n < 0) {
			mantissa *= -1;
		}
		return mantissa;
	}

	public static Vector<Vector<String>> loadAccounts(String accsFileName)
			throws IOException {
		Vector<Vector<String>> accs = new Vector<Vector<String>>();
		File accsFile = new File(accsFileName);
		if (!accsFile.exists()) {
			accsFile.createNewFile();
		}
		Scanner mScanner = new Scanner(accsFile);
		while (mScanner.hasNextLine()) {
			String acc = mScanner.nextLine();
			Vector<String> accAry = new Vector<String>();
			for (String s : acc.split(",")) {
				accAry.add(s);
			}
			try {
				String[] moneyInfo = accAry.get(2).split("月");
				if (moneyInfo != null) {
					int a = Integer.parseInt(moneyInfo[0]);
					int curMonth = Calendar.getInstance().get(Calendar.MONDAY) + 1;
					if (a != curMonth) {
						accAry.set(2, "");
					}
				}
			} catch (Exception e) {
			}
			for (int i = accAry.size(); i < 4; i++) {
				accAry.add("");
			}
			accs.add(accAry);
		}
		mScanner.close();
		return accs;
	}

	public static void writeAccounts(String accsFileName,
			Vector<Vector<String>> accs) throws FileNotFoundException {
		PrintStream ps = new PrintStream(new File(accsFileName));
		for (Vector<String> v : accs) {
			try {
				String[] strings = new String[4];
				v.toArray(strings);
				if (!strings[3].equals("用户名或密码错误")) {
					strings[3] = "";
				}
				ps.println(strings[0] + "," + strings[1] + "," + strings[2]
						+ "," + strings[3]);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		ps.close();
	}

	public static String getProjectPath() {
		String filePath = null;
		try {
			filePath = URLDecoder.decode(Main.class.getProtectionDomain()
					.getCodeSource().getLocation().getFile(), "utf-8");
		} catch (UnsupportedEncodingException e) {
			filePath = "";
			e.printStackTrace();
		}
		if (filePath.endsWith(".jar")) {
			filePath = filePath.substring(0,
					filePath.lastIndexOf(File.separator) + 1);
		}
		java.io.File file = new java.io.File(filePath);
		filePath = file.getAbsolutePath() + File.separator;

		return filePath;
	}
}
